package com.xiaoxin.service;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.xiaoxin.autoconfig.template.HuanXinTemplate;
import com.xiaoxin.commons.utils.Constants;
import com.xiaoxin.dubbo.api.*;
import com.xiaoxin.exception.BusinessException;
import com.xiaoxin.interceptor.UserHolder;
import com.xiaoxin.model.domain.Question;
import com.xiaoxin.model.domain.UserInfo;
import com.xiaoxin.model.dto.RecommendUserDto;
import com.xiaoxin.model.mongo.RecommendUser;
import com.xiaoxin.model.mongo.Visitors;
import com.xiaoxin.model.vo.ErrorResult;
import com.xiaoxin.model.vo.NearUserVo;
import com.xiaoxin.model.vo.PageResult;
import com.xiaoxin.model.vo.TodayBest;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.text.SimpleDateFormat;
import java.util.*;

/**
 * @author xiaoxiaode
 * @date 2021-09-01-15:10
 **/
@SuppressWarnings("all")
@Service
public class MongoService {

    @DubboReference
    private RecommendUserApi recommendUserApi;

    @DubboReference
    private UserInfoApi userInfoApi;

    @DubboReference
    private QuestionApi questionApi;

    @Autowired
    private HuanXinTemplate huanXinTemplate;

    @Value("${project.default.recommend.users}")
    private String RecommendUserId;

    @DubboReference
    private UserLikeApi userLikeApi;

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    @Autowired
    private MessageService messageService;

    @DubboReference
    private UserLocationApi userLocationApi;

    @DubboReference
    private VisitorsApi visitorsApi;

    //查询今日佳人数据
    public TodayBest todayBest() {
        //获取用户id
        Long id = UserHolder.getId();
        //调用api查询
        RecommendUser recommendUser = recommendUserApi.maxScore(id);
        //将recommendUser转化为todayBest对象
        if (recommendUser == null) {
            recommendUser = new RecommendUser();
            recommendUser.setUserId(8L);
            recommendUser.setScore(100D);
        }

        UserInfo userInfo = userInfoApi.findById(recommendUser.getUserId());
        TodayBest vo = TodayBest.init(userInfo, recommendUser);
        //返回
        return vo;
    }

    /*
     * 查询分页好友推荐列表
     * */
    public PageResult recommendation(RecommendUserDto recommendUserDto) {
        //获取用户id
        Long id = UserHolder.getId();
        //调用recommendUserApi分页查询数据列表(PageResult -- recommendUser)
        PageResult pg = recommendUserApi.findUserList(recommendUserDto.getPage(), recommendUserDto.getPagesize(), id);
        //获取分页中的recommendUser数据列表
        List<RecommendUser> items = (List<RecommendUser>) pg.getItems();
        //判断数据是否为空
        if (items == null) {
            return pg;
        }
        //查询所有推荐的用户id列表
        List<Long> userIds = CollUtil.getFieldValues(items, "userId", Long.class);
        UserInfo userInfo = new UserInfo();
        userInfo.setGender(recommendUserDto.getGender());
        userInfo.setAge(recommendUserDto.getAge());
        //构建查询条件,批量查询所有的用户详情
        Map<Long, UserInfo> map = userInfoApi.findByIds(userIds, userInfo);
        //循环推荐的数据列表,构建vo对象
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser item : items) {
            UserInfo info = map.get(item.getUserId());
            if (info != null) {
                TodayBest vo = TodayBest.init(info, item);
                list.add(vo);
            }
        }
        //构造返回值
        pg.setItems(list);
        return pg;
    }

    /*
     * 查看佳人详情
     * */
    public TodayBest personalInfo(Long userId) {
        // 根据用户id查询用户详情
        UserInfo userInfo = userInfoApi.findById(userId);
        // 根据操作人id和查看的用户id,查询两者的缘分值
        Long id = UserHolder.getId();
        RecommendUser recommendUser = recommendUserApi.findScore(userId, id);
        Visitors visitors=new Visitors();
        visitors.setUserId(userId);
        visitors.setVisitorUserId(id);
        visitors.setFrom("首页");
        visitors.setDate(System.currentTimeMillis());
        visitors.setVisitDate(new SimpleDateFormat("yyyyMMdd").format(new Date()));
        visitors.setScore(recommendUser.getScore());
        visitorsApi.save(visitors);
        // 构造返回值
        return TodayBest.init(userInfo, recommendUser);
    }

    /*
     * 查看陌生人问题
     * */
    public String strangerQuestions(Long userId) {
        Question question = questionApi.findByUserId(userId);
        if (question == null) {
            return "你礼貌吗";
        }
        return question.getTxt();
    }

    /*
     * 回复陌生人问题
     * */
    public void reply(Long userId, String reply) {
        Long id = UserHolder.getId();
        UserInfo userInfo = userInfoApi.findById(id);
        Map map = new HashMap();
        map.put("userId", id);
        map.put("huanXinId", Constants.HX_USER_PREFIX + id);
        map.put("nickname", userInfo.getNickname());
        map.put("strangerQuestion", strangerQuestions(userId));
        map.put("reply", reply);
        String message = JSON.toJSONString(map);
        Boolean msg = huanXinTemplate.sendMsg(Constants.HX_USER_PREFIX + userId, message);
        if (!msg) {
            throw new BusinessException(ErrorResult.error());
        }
    }

    /*
     * cards推荐列表
     * */
    public List<TodayBest> recommendCards() {
        //1、调用推荐API查询数据列表（排除喜欢/不喜欢的用户，数量限制）
        List<RecommendUser> recommendUsers = recommendUserApi.findRecommend(UserHolder.getId(), 10);
        //2、判断数据是否存在，如果不存在，构造默认数据
        if (CollUtil.isEmpty(recommendUsers)) {
            recommendUsers = new ArrayList<>();
            String[] userIds = RecommendUserId.split(",");
            for (String userId : userIds) {
                RecommendUser recommendUser = new RecommendUser();
                recommendUser.setUserId(Convert.toLong(userId));
                recommendUser.setToUserId(UserHolder.getId());
                recommendUser.setScore(RandomUtil.randomDouble(60, 90));
                recommendUsers.add(recommendUser);
            }
        }
        //3、构造VO
        List<Long> userId = CollUtil.getFieldValues(recommendUsers, "userId", Long.class);
        Map<Long, UserInfo> map = userInfoApi.findByIds(userId, null);
        List<TodayBest> list = new ArrayList<>();
        for (RecommendUser recommendUser : recommendUsers) {
            UserInfo userInfo = map.get(recommendUser.getUserId());
            if (userInfo != null) {
                TodayBest todayBest = TodayBest.init(userInfo, recommendUser);
                list.add(todayBest);
            }
        }
        return list;
    }

    /*
     * card列表-喜欢
     * */
    public void love(Long likeUserId) {
        // 保存喜欢数据
        boolean save = userLikeApi.likeOrDislike(UserHolder.getId(), likeUserId, true);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        //  将喜欢的数据存入redis中
        //  删除本来不喜欢的redis数据
        redisTemplate.opsForSet().remove(Constants.USER_NOT_LIKE_KEY + UserHolder.getId(), likeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_LIKE_KEY + UserHolder.getId(), likeUserId.toString());
        // 判断是否相互喜欢
        if (isLike(UserHolder.getId(), likeUserId)) {
            // 相互喜欢则添加到好友
            messageService.contacts(likeUserId);
        }
    }

    /*
     * 查询是否相互喜欢
     * */
    public Boolean isLike(Long userId, Long likeUserId) {
        String key = Constants.USER_LIKE_KEY + userId;
        return redisTemplate.opsForSet().isMember(key, likeUserId.toString());
    }

    /*
    * card列表-不喜欢
    * */
    public void unlove(Long unlikeUserId) {
        // 保存喜欢数据
        boolean save = userLikeApi.likeOrDislike(UserHolder.getId(), unlikeUserId, false);
        if (!save) {
            throw new BusinessException(ErrorResult.error());
        }
        // 修改redis中的数据
        redisTemplate.opsForSet().remove(Constants.USER_LIKE_KEY + UserHolder.getId(), unlikeUserId.toString());
        redisTemplate.opsForSet().add(Constants.USER_NOT_LIKE_KEY + UserHolder.getId(), unlikeUserId.toString());
        // 相互喜欢则删除好友
        if (isLike(UserHolder.getId(), unlikeUserId)) {
            // 相互喜欢则添加到好友
            messageService.remove(unlikeUserId);
        }
    }

    /*
    * 搜附近
    * */
    public List<NearUserVo> queryNearUser(String gender, String distance) {
        // 查询附近的用户,location无法序列化 返回id,包含自身id
        List<Long> userIds= userLocationApi.queryNearUser(UserHolder.getId(),Double.valueOf(distance));
        // 判断是否为空
        if(CollUtil.isEmpty(userIds)){
            return new ArrayList<>();
        }
        // userinfo查询详情
        UserInfo info=new UserInfo();
        info.setGender(gender);
        Map<Long, UserInfo> userInfoMap = userInfoApi.findByIds(userIds, info);
        // 构造返回
        List<NearUserVo> vos=new ArrayList<>();
        for (Long userId : userIds) {
            if(userId==UserHolder.getId()){
                continue;
            }
            UserInfo userInfo = userInfoMap.get(userId);
            if(userInfo!=null){
                NearUserVo vo = NearUserVo.init(userInfo);
                vos.add(vo);
            }
        }
        return vos;
    }
}
